/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package controller;

import static com.sun.xml.ws.security.addressing.impl.policy.Constants.logger;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import static controller.BusControl.getApplications;
import docs.InternshipCompanyModel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpSession;
import model.Applications;
import model.Internship;
import model.Notification;
import model.Utilisateur;
import org.netbeans.xml.schema.elements.APPLICATION;
import org.netbeans.xml.schema.elements.APPLICATIONTYPE;
import org.netbeans.xml.schema.elements.COMPANYTYPE;
import org.netbeans.xml.schema.elements.LISTIDTYPE;
import org.netbeans.xml.schema.elements.NOTIF;
import org.netbeans.xml.schema.elements.STUDENTTYPE;
import org.netbeans.xml.schema.elements.NOTIFSTYPE;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

/**
 *
 * @author metbill
 */
@Controller
public class InternshipController {
 
    
    /**
     * Search an internship
     * Function is used by the student to search an internship. 
     * This function calls the web service of the company with several parameters.
     */
    @RequestMapping(value = "/searchInternship", method = RequestMethod.POST)
    public String searchInternship ( @ModelAttribute("SpringWeb")docs.InternshipInputModel internSearch, ModelMap model ,HttpSession session) {

        // S'il n'y a pas de session en cours, c'est que l'utilisateur n'est pas connecté. Sinon, on se connecte normalement.
       if (session.getAttribute("userID") != null ){ 
            int idUser = (int) session.getAttribute("userID");
            
            //Association Company - list Internships
            //HashMap<Integer,ArrayList<Internship>> internsCompany = new HashMap<Integer,ArrayList<Internship>>();
            HashMap<String,ArrayList<Internship>> internsCompany = new HashMap<String,ArrayList<Internship>>();
            //Id list of the companies
            List<Integer> listId= BusControl.getCompanies().getID();
            
            //Getting the offers of each company
            for(Integer idCom: listId){
                            
                // La réponse est sous forme de liste de stage. On va ici les mettre au format voulu pour pouvoir les afficher.
                List<docs.InternshipCompanyModel> offers =  BusControl.getOffers(internSearch);
                ArrayList<Internship> listOffer= new ArrayList<Internship>();
                             
                if (offers != null){
                    Iterator<docs.InternshipCompanyModel> ite = offers.iterator();
                    while (ite.hasNext()){
                         docs.InternshipCompanyModel offer = ite.next();
                         Internship intern = new Internship(offer.getInternshipID(),offer.getTitle(),offer.getDescription(),offer.getDuration()
                         ,offer.getLocation(), offer.getStatus(), offer.getStudyDomain(), offer.getContact(), offer.getType(), offer.getStartDate()
                         ,offer.getSalary());
                         listOffer.add(intern);
                     }
                } else {
                    listOffer = null;
                }
                String nameCom = BusControl.getCompanybyId(idCom.intValue()).getNOM();
                internsCompany.put(nameCom, listOffer);
            }

             model.addAttribute("listOffer", internsCompany);
             
                                    
            // La réponse est sous forme de liste de stage. On va ici les mettre au format voulu pour pouvoir les afficher.
             //Bonne version
            /* List<docs.InternshipCompanyModel> offers =  BusControl.getOffers(internSearch);
             ArrayList<Internship> listOffer= new ArrayList<Internship>();
             if (offers != null){
             Iterator<docs.InternshipCompanyModel> ite = offers.iterator();
              while (ite.hasNext()){
                  docs.InternshipCompanyModel offer = ite.next();
                  Internship intern = new Internship(offer.getInternshipID(),offer.getTitle(),offer.getDescription(),offer.getDuration()
                  ,offer.getLocation(), offer.getStatus(), offer.getStudyDomain(), offer.getContact(), offer.getType(), offer.getStartDate()
                  ,offer.getSalary());
                  listOffer.add(intern);
              }
             } else {
                 listOffer = null;
             }        
             model.addAttribute("listOffer", listOffer);*/
             
             // On prépare la mise en page.
             Utils.drawHomePage(session.getAttribute("userName").toString(), BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "internships", model);            
            return "home";
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        }
    }
    
    
    /**
     * View internship details
     * Function is used by the student to see all the internship details.
     * @param internSelected
     * @param model
     * @param session
     * @return 
     */
    //View the details of an internship (not completed)
    @RequestMapping(value = "/detailsInternship", method = RequestMethod.GET)
    public String detailsInternship ( @ModelAttribute("SpringWeb")docs.InternshipCompanyModel internSelected, ModelMap model , HttpSession session) {
        
       // S'il n'y a pas de session en cours, c'est que l'utilisateur n'est pas connecté. Sinon, on se connecte normalement.
       if (session.getAttribute("userID") != null ){ 
            int idUser = (int) session.getAttribute("userID"); 
            model.addAttribute("detailOffer", internSelected);
            // On prépare la mise en page.
            Utils.drawHomePage(session.getAttribute("userName").toString(), BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "internshipDetail", model); 
            return "home";
            
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        } 
    }
    
    /**
     * Application form
     * @param internSelected
     * @param model
     * @param session
     * @return 
     */
    @RequestMapping(value = "/formulApply", method = RequestMethod.GET)
    public String formulApply ( @ModelAttribute("SpringWeb")docs.InternshipCompanyModel internSelected, ModelMap model , HttpSession session) {
       // S'il n'y a pas de session en cours, c'est que l'utilisateur n'est pas connecté. Sinon, on se connecte normalement.
        if (session.getAttribute("userID") != null ){ 
            int idUser = (int) session.getAttribute("userID"); 
            System.out.println("COUCOU DU DETAIL INTERNSHIP "+internSelected);
            model.addAttribute("detailOffer", internSelected);
            Utils.drawHomePage(session.getAttribute("userName").toString(), BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "internshipApply", model); 
            return "home";
            
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        } 
    }
        
    /**
     * Apply for an offer
     * @param application
     * @param model
     * @param session
     * @return 
     */
    @RequestMapping(value = "/FileUpload", method = RequestMethod.POST)
    public static String applyInternship (@ModelAttribute("SpringWeb")docs.ApplicationModel application, ModelMap model,
            HttpSession session) {
        
        System.out.println("Dans le APPLY");
        if (session.getAttribute("userID") != null ){ 
            int idUser = (int) session.getAttribute("userID"); 
            STUDENTTYPE user = BusControl.getStudentbyId(idUser);
            application.setFirstName((String) user.getFIRSTNAME());
            application.setLastName((String) user.getLASTNAME());
            application.setMail((String) user.getMAIL());
            System.out.println(application.getMail());
            
            System.out.println("L'intenrshipID "+application.getInternshipID());
            System.out.println("CV FIRST NAME : "+application.getCvPath());
            System.out.println("CL FIRST NAME : "+application.getClPath());
            System.out.println("APPLY FIRST NAME : "+application.getFirstName());
            System.out.println("APPLY MAIL : "+application.getMail());
            BusControl.addNewApplicant(application);
            
            Utils.drawHomePage(session.getAttribute("userName").toString(), BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "internshipDetail", model); 
            return "home";
        
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        }
    }
    
    
    
   
    @RequestMapping(value = "/uploadMultipleFile", method = RequestMethod.POST)
    public String uploadMultipleFileHandler(@ModelAttribute("SpringWeb")docs.ApplicationModel application, ModelMap model,
            HttpSession session, @RequestParam("file") MultipartFile[] files) {
        
        if (session.getAttribute("userID") != null ){ 
            int idUser = (int) session.getAttribute("userID"); 
            STUDENTTYPE user = BusControl.getStudentbyId(idUser);
            
            
            application.setFirstName((String) user.getFIRSTNAME());
            application.setLastName((String) user.getLASTNAME());
            application.setMail((String) user.getMAIL());
            
            for (int i = 0; i < files.length; i++) {
                MultipartFile file = files[i];
                System.out.println("Taille : "+file.getSize());

                try {
                    byte[] bytes = file.getBytes();
                    file.getInputStream().read(bytes);
                    System.out.println("URL retournée : "+BusControl.uploadCV(bytes));
                    if(i==0)
                        application.setCvPath(BusControl.uploadCV(bytes));
                    if(i==1)
                        application.setClPath(BusControl.uploadCV(bytes));
                } catch (Exception e) {}
            }
            
            //Ajouter une application à la BD Entreprise
            int applicationID = BusControl.addNewApplicant(application);
            
            //Ajouter une application à la BD
            BusControl.createApplication(idUser, 3, applicationID, 0);
            
            //mise à jour de la liste de candidature
                    APPLICATIONTYPE listCand = getApplications(idUser);
                    ArrayList<Applications> listCan= new ArrayList<>();
                    
                    if (listCand != null){
                    Iterator<APPLICATION> ite = listCand.getAPPLICATIONS().iterator();
                     while (ite.hasNext()){
                         APPLICATION offer = ite.next();
                         InternshipCompanyModel inte = BusControl.getOffersById(BusControl.getAppById(offer.getApplicationID()).getInternshipID());
                         int statusId=BusControl.getAppById(offer.getApplicationID()).getStatus();
                          String status = Utils.getStatus(statusId);
                         COMPANYTYPE com = BusControl.getCompanybyId(offer.getCompanyID());
                         
                         Applications can = new Applications(offer.getApplicationID(),null,inte, com.getNOM(), com.getMAIL(), com.getADDRESS(), status);
                         if (statusId != 4){ 
                             listCan.add(can);
                         }
                         
                     }
                    } else {
                        listCan = null;
                    }
                    model.addAttribute("listCan", listCan);
            
            Utils.drawHomePage(session.getAttribute("userName").toString(), BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "candidatureStudent", model); 
            return "home";
        } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        }
    }
    
    /**
     * The application is cancelled.
     * The status of the application is changed in the process from x to 4.
     * Cancelling after asking the convention is not allowed.
     * The list is loaded again.
     * @param id
     * @param model
     * @param session
     * @return 
     */
    @RequestMapping(value = "/cancelApplication/{id}", method = RequestMethod.GET)
    public String cancelApplication ( @PathVariable("id") int id, ModelMap model , HttpSession session) {
        
        // S'il n'y a pas de session en cours, c'est que l'utilisateur n'est pas connecté. Sinon, on se connecte normalement.
       if (session.getAttribute("userID") != null ){ 
           
          int idUser = (int) session.getAttribute("userID"); 
        //Boolean success = BusControl.updateApplicationStatus(4, id);
       
                
        APPLICATIONTYPE listCand = getApplications(idUser);
        ArrayList<Applications> listCan= new ArrayList<Applications>();
        int oldStatus = 0;
        if (listCand != null){
            Iterator<APPLICATION> ite = listCand.getAPPLICATIONS().iterator();
            while (ite.hasNext()){
                  APPLICATION offer = ite.next();
                  InternshipCompanyModel inte = BusControl.getOffersById(BusControl.getAppById(offer.getApplicationID()).getInternshipID());
                  //String status = Utils.getStatus(offer.getState());
                  String status = Utils.getStatus(BusControl.getAppById(offer.getApplicationID()).getStatus());
                  COMPANYTYPE com = BusControl.getCompanybyId(offer.getCompanyID());
                  Applications can = null;
                  if (offer.getApplicationID() == id){
                         //oldStatus =  offer.getState();
                            oldStatus = BusControl.getAppById(offer.getApplicationID()).getStatus();
                         if (oldStatus < 8 ){
                              BusControl.updateApplicationStatus(4, id);
                              can = new Applications(offer.getApplicationID(),null,inte, com.getNOM(), com.getMAIL(), com.getADDRESS(), "4");
                         } else {
                             model.addAttribute("errormessage", " You are engaged. You can not cancel your application. ");
                         }
                      
                  } else {
                      can = new Applications(offer.getApplicationID(),null,inte, com.getNOM(), com.getMAIL(), com.getADDRESS(), status);
                  }
                                           
                  int stat = BusControl.getAppById(can.getApplicationId()).getStatus();
                         
                    //On n'affiche pas les stages refuse par l'etudiant
                         if (stat != 4){              
                            listCan.add(can);           
                         }
             }
         } else {
             listCan = null;
         }
        model.addAttribute("listCan", listCan);
        Utils.drawHomePage(session.getAttribute("userName").toString(),  BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "candidatureStudent", model);
        return "home";
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        }
    }
    
    /**
     * Ask the convention
     * The student can ask the convention. 
     * The status of the process will be changed from 6 to 8.
     * The student can't ask two or more conventions.
     * @param id
     * @param model
     * @param session
     * @return 
     */
    @RequestMapping(value = "/askConvention/{id}", method = RequestMethod.GET)
    public String askConvention ( @PathVariable("id") int id, ModelMap model , HttpSession session) {
        
       Boolean already = false;
       int index = id;
       int toto = id;
       int oldStatus = 0;
       if (session.getAttribute("userID") != null ){ 
          int idUser = (int) session.getAttribute("userID"); 
       
         APPLICATIONTYPE listCand = getApplications(idUser);   
         ArrayList<Applications> listCan= new ArrayList<Applications>();
         if (listCand != null){
             Iterator<APPLICATION> ite = listCand.getAPPLICATIONS().iterator(); 
                 while (ite.hasNext()){
                     APPLICATION offer = ite.next();
                     InternshipCompanyModel inte = BusControl.getOffersById(BusControl.getAppById(offer.getApplicationID()).getInternshipID());
                     
                    if (BusControl.getAppById(offer.getApplicationID()).getStatus()>= 8){
                        already = true;
                        index = offer.getApplicationID();
                    }
                     int statusId=BusControl.getAppById(offer.getApplicationID()).getStatus();
                     String status = Utils.getStatus(statusId);
                         
                     COMPANYTYPE com = BusControl.getCompanybyId(offer.getCompanyID());
                     Applications can = new Applications(offer.getApplicationID(),null,inte, com.getNOM(), com.getMAIL(), com.getADDRESS(), status);
                                             
                     //int stat = BusControl.getAppById(can.getApplicationId()).getStatus();  
                     //On n'affiche pas les stages refuse par l'etudiant
                         if (statusId != 4){              
                            listCan.add(can);           
                         }
                     //listCan.add(can);
                     if (offer.getApplicationID() == id){
                         //oldStatus =  offer.getState();
                         oldStatus = statusId;
                         System.out.println("status application : "+oldStatus);
                         toto = listCan.size()-1;
                         System.out.println("id dans la liste :"+toto);
                     }
                 }
         } else {
             listCan = null;
         }
         if (already == false){
             if (oldStatus == 6){
                BusControl.updateApplicationStatus(8,id);
                listCan.get(toto).setStatus("Convention asked");
             } else {
                 model.addAttribute("errormessage", "You can't ask your convention yet.");
             }
         } else if (index != id) {
             model.addAttribute("errormessage", "You have already asked a convention.");
         }
         model.addAttribute("listCan", listCan);
         Utils.drawHomePage(session.getAttribute("userName").toString(),  BusControl.getNotifications(idUser).getNOTIFS().size(), "searchStudent", "candidatureStudent", model);
         return "home";
         } else {
            model.addAttribute("errormessage", " You need to be authenticated. ");
            return "connection";
        }   
    }
            
            
}
